using Core.FrameWork.Commons.App;
using Core.FrameWork.Commons.Loging;
using Core.FrameWork.Models;
using Core.Web.Api.Middleware;
using Core.Web.Api.Utils.Converter;
using Core.Web.Api.Utils.HttpContextUser;
using Core.Web.Api.Utils.Init;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
using Swashbuckle.AspNetCore.SwaggerUI;
using System;

namespace Core.Web.Api
{
    /// <summary>
    /// 启动类
    /// </summary>
    public class Startup
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="environment"></param>
        public Startup(IConfiguration configuration, IWebHostEnvironment environment)
        {
            Configuration = configuration;
            Environment = environment;

            //手动注册监听配置文件更新回调
            ChangeToken.OnChange(() => configuration.GetReloadToken(), () => {
                Console.WriteLine("配置更新");
            });

        }
        public IConfiguration Configuration { get; }
        public IWebHostEnvironment Environment { get; }

        /// <summary>
        /// 容器注入
        /// </summary>
        /// <param name="services"></param>
        public void ConfigureServices(IServiceCollection services)
        {


            services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            services.AddControllers().AddJsonOptions(option =>
            {
                option.JsonSerializerOptions.Converters.Add(new DateTimeConverter());
            });
            //初始化全局配置
            AppCenter.Services = services;
            AppCenter.Configuration = Configuration;
            AppCenter.webHostEnvironment = Environment;

            services.UseSwaggerChinese();//Swagger中文文档
            services.UseCache();//缓存中间件
            services.UseJWTAuthentication();//JWT验证
            services.InitUploadFile();//配置上传文件
            services.AddCorsSetup(); //跨域配置
            services.InitHttpClientPolly();//增加HttpClientFactory-Polly机制


            services.TryAddTransient<IHttpContextUser, HttpContextUser>();//获取Token 用户上下文

            //使用数据库链接池
            services.AddDbContextPool<ApplicationContext>(options =>
            {
                var loggerFactory = new LoggerFactory();
                loggerFactory.AddProvider(new EFCoreLoggerProvider());
                options.UseLazyLoadingProxies().UseMySql(APIConfig.DbConnections.ConnectionString, ServerVersion.Parse("8.0.1")).UseLoggerFactory(loggerFactory);
            });
            services.AddHttpClient();  //注入HttpClient
        }

        /// <summary>
        /// 管道
        /// </summary>
        /// <param name="app"></param>
        public void Configure(IApplicationBuilder app, IHostApplicationLifetime hostApplicationLifetime)
        {
            if (Environment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();

            }

            hostApplicationLifetime.ApplicationStopped.Register(LogHostLifetime.OnStopped);

            #region 开启Swagger
            //是否开始Swagger
            if (APIConfig.ApiSetting.UseSwagger)
            {
                app.UseSwagger();
                app.UseSwaggerUI(c =>
                {
                    c.SwaggerEndpoint("/swagger/v1/swagger.json", "Core.Web.Api v1");  //注入汉化文件
                    c.InjectJavascript($"/swagger/swagger_translator.js");
                    c.InjectStylesheet($"/swagger/Swagger.css");
                    c.DocExpansion(DocExpansion.None); //界面打开时自动折叠
                });
            }
            #endregion
            app.UseCors(APIConfig.ApiSetting.CorsPolicyName);//跨域配置

            app.UseMiddleware<ExceptionHandlerMiddleware>();//全局异常配置
            app.UseMiddleware<IPLogHandlerMiddleware>();//配置IP记录
            app.UseMiddleware<RecordHandlerAccessLogsMiddleware>();//配置用户操作记录


            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

    }
}
